package com.lzx.httpclient;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class HttpPost {

	private List<AbstractBody> list;
	private URL url;
	private HeaderGroup headerGroup;

	
	private Socket socket;

	public HttpPost(URL url) {
		list = new ArrayList();
		this.url = url;
		headerGroup = new HeaderGroup();
	}

	public void addField(AbstractBody ab) {
		list.add(ab);
	}

	public void execute() {
		try {

			socket = new Socket(url.getHost(), url.getPort());
			OutputStream os = socket.getOutputStream();
			send(os);
			for (AbstractBody ab : list) {
				ab.writeTo(os, true);

			}

			os.write(("--" + AbstractBody.boundary + "--\r\n").getBytes());
			

			BufferedReader br = new BufferedReader(new InputStreamReader(socket
					.getInputStream(), "UTF-8"));
			String buffer;
			while ((buffer = br.readLine()) != null) {
				System.out.println(buffer);
			}	
			
			br.close();
			os.close();

		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			
			try {
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

	public void send(OutputStream os) throws IOException {
		String LR = "\r\n";
		StringBuilder sb = new StringBuilder();
		sb.append("POST " + url.getPath() + " HTTP/1.1" + LR);
		sb.append("Host: " + url.getHost() + LR);
		if (headerGroup.list != null)
			for (Header header : headerGroup.list) {
				sb.append(header.getName() + ": " + header.getValue() + LR);
			}

		sb.append("Content-Type: multipart/form-data; boundary="
				+ AbstractBody.boundary + LR);
		sb.append("Content-Length: " + getTotalLength() + LR);
		sb.append(LR);

		os.write(sb.toString().getBytes());
		System.out.print(sb);
	}

	/**
	 * 计算 Content-length
	 * @return
	 */
	public long getTotalLength() {
		long length = 0;
		//�������ݵ��ֽ���
		for (AbstractBody ab : list) {
			length += ab.getContentLength();

		}
		//���б߽���ֽ���
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		for (AbstractBody ab : list) {
			ab.writeTo(os, false);
		}
		int extra = os.toByteArray().length;		
		try {
			os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//�������ֽ���
		int end = ("--" + AbstractBody.boundary + "--\r\n").getBytes().length;
		
		return length + extra + end;
	}

	public HeaderGroup getHeaderGroup() {
		return headerGroup;
	}

	public void setHeaderGroup(HeaderGroup headerGroup) {
		this.headerGroup = headerGroup;
	}

}
